﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Netfraction.ClientInterface
{
    [Flags()]
    public enum ChatOptions
    {
        None = 0,
        METext = 1,
        PublicMessage = 2,
        PrivateMessage = 4,
        GroupPrivateMessage = 8,
        HubMessage = 16
    }

    public class ChatEventArgs : EventArgs
    {
        public Identity Source { get; set; }
        public Identity Target { get; set; }
        public Identity RespondTo { get; set; }
        public string MessageText { get; set; }
        public ChatOptions ChatOptions { get; set; }

        public ChatEventArgs(Identity sourceIdentity, Identity targetIdentity, Identity responseIdentity, string messageText, ChatOptions chatOptions)
        {
            this.Source = sourceIdentity;
            this.Target = targetIdentity;
            this.RespondTo = responseIdentity;
            this.MessageText = messageText;
            this.ChatOptions = chatOptions;
        }
    }

    public delegate void ChatMessageEventHandler(ChatEventArgs e);
    
    public class Chat
    {
        /// <summary>
        /// 
        /// </summary>
        /// <parameter name="sourceIdentity">The identity of the peer who sent the message.</parameter>
        /// <parameter name="targetIdentity">If ChatOptions.PrivateMessage or ChatOptions.GroupPrivateMessage is set, this is the intended recipient of the message.</parameter>
        /// <parameter name="responseIdentity">This is null unless the ChatOptions.GroupPrivateMessage flag is set.</parameter>
        /// <parameter name="messageText">The message text.</parameter>
        /// <parameter name="chatOptions">Additional options specifying how to interpret the message.</parameter>

        public static event ChatMessageEventHandler OnChatMessageReceived;

        public static void ChatMessageReceived(Identity sourceIdentity, Identity targetIdentity, Identity responseIdentity, string messageText, ChatOptions chatOptions)
        {
            if (OnChatMessageReceived != null)
                OnChatMessageReceived(new ChatEventArgs(sourceIdentity, targetIdentity, responseIdentity, messageText, chatOptions));
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification="Only hub nodes can route chat messages.")]
        public static void SendPublicMessage(RemoteMachine.Hub hub, string message)
        {
            bool isMEText = message.StartsWith("/me ");

            Network.Protocol.ProtocolMessageFactory factory = new Network.Protocol.BASE.Factory.FactoryMSG();

            Dictionary<int, object> factoryParams = new Dictionary<int, object>();

            factoryParams.Add((int)Network.Protocol.BASE.Factory.FactoryMSG.ParameterEnum.SessionID, hub.SessionId);
            factoryParams.Add((int)Network.Protocol.BASE.Factory.FactoryMSG.ParameterEnum.Text, isMEText ? message.Substring(4) : message);

            if (isMEText)
                factoryParams.Add((int)Network.Protocol.BASE.Factory.FactoryMSG.ParameterEnum.METext, (int)Network.Protocol.BASE.Factory.FactoryMSG.METextTypesEnum.IRCNickText);

            hub.Connection.Send(factory.Create(Network.Protocol.ProtocolMessage.MessageTypeEnum.Broadcast, factoryParams).ToString());
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "Only hub nodes can route chat messages.")]
        public static void SendPrivateMessage(RemoteMachine.Hub hub, Identity target, string message)
        {
            bool isMEText = message.StartsWith("/me ");

            Network.Protocol.ProtocolMessageFactory factory = new Network.Protocol.BASE.Factory.FactoryMSG();

            Dictionary<int, object> factoryParams = new Dictionary<int, object>();

            factoryParams.Add((int)Network.Protocol.BASE.Factory.FactoryMSG.ParameterEnum.SessionID, hub.SessionId);
            factoryParams.Add((int)Network.Protocol.BASE.Factory.FactoryMSG.ParameterEnum.TargetID, Managers.PeerManager.GetInstance()[target.ClientId].SessionId);
            factoryParams.Add((int)Network.Protocol.BASE.Factory.FactoryMSG.ParameterEnum.Text, isMEText ? message.Substring(4) : message);
            factoryParams.Add((int)Network.Protocol.BASE.Factory.FactoryMSG.ParameterEnum.PrivateMessage, hub.SessionId);

            if (isMEText)
                factoryParams.Add((int)Network.Protocol.BASE.Factory.FactoryMSG.ParameterEnum.METext, (int)Network.Protocol.BASE.Factory.FactoryMSG.METextTypesEnum.IRCNickText);

            hub.Connection.Send(factory.Create(Network.Protocol.ProtocolMessage.MessageTypeEnum.Echo, factoryParams).ToString());
        }
    }
}
